#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>

#define LEFT 30000000
#define RIGHT 30000200
#define THRNUM 4
#define N 3

static int num = 0;
static pthread_mutex_t mut_num;

static void *thread_primer(void *p);




int main(int argc, char **argv)
{
    int i;
    int err;
    pthread_t tid[THRNUM];
    for (i = 0; i < THRNUM; i++)
    {
        err = pthread_create(tid + i, NULL, thread_primer, (void*)i);
        if (err > 0)
        {
            fprintf(stderr, "pthread create error\n");
            exit(1);
        }
    }

    for(i=LEFT; i<RIGHT; i++)
    {
        pthread_mutex_lock(&mut_num);

        while(num != 0)
        {
            num = i;
            pthread_mutex_unlock(&mut_num);
            sched_yield();
            pthread_mutex_lock(&mut_num);
        }
        num = i;
        pthread_mutex_unlock(&mut_num);

    }
    pthread_mutex_lock(&mut_num);
    while(num != 0)
    {
        pthread_mutex_unlock(&mut_num);
        sched_yield();
        pthread_mutex_lock(&mut_num);
    }
    num = -1;
    pthread_mutex_unlock(&mut_num);



    for (i = 0; i < THRNUM; i++)
    {
        pthread_join(tid[i],NULL);
    }

    pthread_mutex_destroy(&mut_num);
    exit(0);
}

static void *thread_primer(void *p)
{
    int i,mark, j ;


    while(1)
    {
        pthread_mutex_lock(&mut_num);
        while(num == 0)
        {
            pthread_mutex_unlock(&mut_num);
            sched_yield();
            pthread_mutex_lock(&mut_num);        
        }
        if(num < 0)
        {
            pthread_mutex_unlock(&mut_num);
            pthread_exit(NULL);
        }
        i = num;
        num = 0;
        pthread_mutex_unlock(&mut_num);

        for (j = 2; j < i / 2; j++)
        {
            mark = 1;
            if (i % j == 0)
            {
                mark = 0;
                break;
            }
        }

        if (mark)
        {
            printf("[%d]%d is a primer\n", (int)p, i);
        }
    }

}
